package com.example.service;

import com.example.data.entity.kg.KgEntity;
import com.example.data.entity.QuestionInfo;
import com.example.data.mapper.KgEntityMapper;
import com.example.data.mapper.TripleMapper;
import com.example.data.vo.Triple;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import jakarta.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 基于Triple和TripleMapper的完整问答服务实现
 * 支持实体模糊匹配、常识回答和友好交互提示
 */
@Service
public class QAService {

    private static final Logger log = LoggerFactory.getLogger(QAService.class);

    // 1. 历史常识库（覆盖基础历史知识，不依赖实体关系表）
    private final Map<String, String> commonKnowledgeBase = new HashMap<String, String>() {{
        // 人物相关
        put("秦始皇是谁", "秦始皇（前259年-前210年），嬴姓，赵氏，名政，是中国历史上第一个称皇帝的君主，完成了统一六国的大业。");
        put("项羽是什么人", "项羽（前232年-前202年），名籍，字羽，秦末起义领袖，军事家，以勇猛著称，最终在楚汉争霸中败于刘邦。");
        put("刘邦是谁", "刘邦（前256年-前195年），即汉高祖，秦末起义领袖，汉朝开国皇帝，击败项羽后建立西汉。");

        // 事件相关
        put("巨鹿之战是什么", "巨鹿之战（前207年）是秦末项羽率领楚军与秦军主力的决战，项羽破釜沉舟大败秦军，奠定反秦基础。");
        put("鸿门宴的故事", "鸿门宴是公元前206年刘邦与项羽在咸阳附近的宴会，项羽谋士范增欲杀刘邦，最终刘邦脱险。");

        // 朝代相关
        put("秦朝存在了多少年", "秦朝（前221年-前207年）共存在14年，是中国历史上第一个大一统中央集权王朝。");
        put("汉朝什么时候建立的", "汉朝由刘邦于公元前202年建立，分为西汉和东汉，共延续约400年。");
    }};

    @Resource
    private QuestionAnalyzer questionAnalyzer;

    @Resource
    private KgEntityMapper kgEntityMapper;

    @Resource
    private TripleMapper tripleMapper;

    @Resource
    private AnswerGenerator answerGenerator;

    /**
     * 处理用户问题的主入口
     */
    public String answerQuestion(String question) {
        // 输入合法性校验
        if (question == null || question.trim().isEmpty()) {
            log.warn("收到空问题请求");
            return "请输入有效的历史问题，例如：“秦始皇统一了哪些国家？”";
        }

        String processedQuestion = question.trim();
        log.info("开始处理问题：{}", processedQuestion);

        try {
            // 2. 优先查询常识库（无需实体关系数据）
            String commonAnswer = queryCommonKnowledge(processedQuestion);
            if (commonAnswer != null) {
                log.info("常识库匹配成功，问题：{}", processedQuestion);
                return commonAnswer;
            }

            // 3. 分析问题提取关键信息
            QuestionInfo questionInfo = questionAnalyzer.analyze(processedQuestion);
            if (questionInfo == null) {
                log.error("问题分析失败，无法提取关键信息");
                return generateUnrecognizedPrompt(processedQuestion);
            }

            log.info("问题分析结果 - 实体: {}, 关系: {}, 头实体: {}, 尾实体: {}",
                    questionInfo.getEntities(),
                    questionInfo.getRelationType(),
                    questionInfo.getKnownHeadEntity(),
                    questionInfo.getKnownTailEntity());

            // 4. 精确查询相关三元组
            List<Triple> exactTriples = queryExactTriples(questionInfo);

            // 5. 精确查询无结果时尝试模糊查询
            if (exactTriples.isEmpty()) {
                log.info("精确查询无结果，触发模糊查询");
                exactTriples = queryFuzzyTriples(questionInfo);
            }

            // 6. 根据查询结果生成回答
            return exactTriples.isEmpty()
                    ? generateNoResultResponse(questionInfo)
                    : answerGenerator.generateNaturalAnswer(processedQuestion, exactTriples);

        } catch (Exception e) {
            log.error("处理问题时发生异常: {}", processedQuestion, e);
            return "抱歉，处理您的问题时出现错误，请稍后重试";
        }
    }

    /**
     * 查询常识库（支持精确匹配和关键词模糊匹配）
     */
    private String queryCommonKnowledge(String question) {
        // 预处理问题：去除标点和语气词
        String normalizedQuestion = question
                .replaceAll("[？?。，,！!；;：:]", "")
                .replaceAll("(请问|你知道|告诉我|能说下|吗|呢|一下)", "")
                .trim()
                .toLowerCase();

        // 精确匹配
        if (commonKnowledgeBase.containsKey(normalizedQuestion)) {
            return commonKnowledgeBase.get(normalizedQuestion);
        }

        // 关键词模糊匹配（问题包含关键词或关键词包含问题）
        for (Map.Entry<String, String> entry : commonKnowledgeBase.entrySet()) {
            String key = entry.getKey().toLowerCase();
            if (normalizedQuestion.contains(key) || key.contains(normalizedQuestion)) {
                return entry.getValue();
            }
        }

        return null;
    }

    /**
     * 生成无法识别问题的提示
     */
    private String generateUnrecognizedPrompt(String question) {
        List<String> possibleEntities = extractPotentialEntities(question);
        if (!possibleEntities.isEmpty()) {
            return String.format("抱歉，我没理解您的问题。您可能在查询关于“%s”的信息？\n" +
                            "可以尝试这样问：\n" +
                            "- “%s的主要成就是什么？”\n" +
                            "- “%s相关的历史事件有哪些？”",
                    String.join("”或“", possibleEntities),
                    possibleEntities.get(0),
                    possibleEntities.get(0));
        } else {
            return "抱歉，未能理解您的问题。请尝试询问具体的历史人物、事件或关系，例如：\n" +
                    "- “项羽和刘邦是什么关系？”\n" +
                    "- “赤壁之战发生在什么时候？”";
        }
    }

    /**
     * 提取问题中可能的实体（基于历史关键词库）
     */
    private List<String> extractPotentialEntities(String question) {
        // 历史实体关键词库（按类型分类）
        List<String> personEntities = Arrays.asList("秦始皇", "嬴政", "刘邦", "项羽", "汉武帝", "曹操", "刘备", "诸葛亮");
        List<String> eventEntities = Arrays.asList("巨鹿之战", "楚汉争霸", "鸿门宴", "赤壁之战", "焚书坑儒", "文景之治");
        List<String> dynastyEntities = Arrays.asList("秦朝", "汉朝", "西汉", "东汉", "三国", "曹魏", "蜀汉", "东吴");
        List<String> placeEntities = Arrays.asList("咸阳", "长安", "洛阳", "赤壁", "乌江", "鸿门");

        // 合并所有关键词并按长度排序（长词优先匹配）
        List<String> allEntities = new ArrayList<>();
        allEntities.addAll(personEntities);
        allEntities.addAll(eventEntities);
        allEntities.addAll(dynastyEntities);
        allEntities.addAll(placeEntities);
        allEntities.sort((a, b) -> Integer.compare(b.length(), a.length())); // 长词优先

        // 匹配问题中的实体
        Set<String> matchedEntities = new HashSet<>();
        String lowerQuestion = question.toLowerCase();

        for (String entity : allEntities) {
            if (lowerQuestion.contains(entity.toLowerCase())) {
                matchedEntities.add(entity);
                // 匹配后移除，避免重复匹配（如"嬴政"和"秦始皇"）
                lowerQuestion = lowerQuestion.replace(entity.toLowerCase(), "");
            }
        }

        return new ArrayList<>(matchedEntities);
    }

    /**
     * 精确查询三元组（基于TripleMapper的所有方法）
     */
    private List<Triple> queryExactTriples(QuestionInfo questionInfo) {
        // 1. 头实体+关系类型查询（优先级最高）
        if (questionInfo.getKnownHeadEntity() != null) {
            KgEntity headEntity = kgEntityMapper.selectByNameAndType(questionInfo.getKnownHeadEntity(), null);
            if (headEntity != null) {
                List<Triple> triples = questionInfo.getRelationType() != null
                        ? tripleMapper.selectTriplesByHeadEntityIdAndRelationType(headEntity.getId(), questionInfo.getRelationType())
                        : tripleMapper.selectTriplesByHeadEntityId(headEntity.getId());

                if (!triples.isEmpty()) {
                    log.info("头实体查询命中 {} 条三元组", triples.size());
                    return filterValidTriples(triples);
                }
            }
        }

        // 2. 尾实体+关系类型查询
        if (questionInfo.getKnownTailEntity() != null) {
            KgEntity tailEntity = kgEntityMapper.selectByNameAndType(questionInfo.getKnownTailEntity(), null);
            if (tailEntity != null) {
                List<Triple> triples = questionInfo.getRelationType() != null
                        ? tripleMapper.selectTriplesByTailEntityIdAndRelationType(tailEntity.getId(), questionInfo.getRelationType())
                        : tripleMapper.selectTriplesByTailEntityId(tailEntity.getId());

                if (!triples.isEmpty()) {
                    log.info("尾实体查询命中 {} 条三元组", triples.size());
                    return filterValidTriples(triples);
                }
            }
        }

        // 3. 实体列表查询（取最长实体优先）
        if (!questionInfo.getEntities().isEmpty()) {
            // 优先选择最长的实体，降低短实体误匹配概率
            String targetEntity = questionInfo.getEntities().stream()
                    .max(Comparator.comparingInt(String::length))
                    .orElse("");

            KgEntity entity = kgEntityMapper.selectByNameAndType(targetEntity, null);
            if (entity != null) {
                // 查询该实体作为头和尾的所有三元组
                List<Triple> headTriples = tripleMapper.selectTriplesByHeadEntityId(entity.getId());
                List<Triple> tailTriples = tripleMapper.selectTriplesByTailEntityId(entity.getId());

                // 合并并去重
                Set<Triple> mergedTriples = new HashSet<>(headTriples);
                mergedTriples.addAll(tailTriples);

                if (!mergedTriples.isEmpty()) {
                    log.info("实体查询命中 {} 条三元组", mergedTriples.size());
                    return new ArrayList<>(mergedTriples);
                }
            }
        }

        // 4. 仅关系类型查询（兜底）
        if (questionInfo.getRelationType() != null) {
            List<Triple> triples = tripleMapper.selectTriplesByRelationType(questionInfo.getRelationType());
            if (!triples.isEmpty()) {
                log.info("关系类型查询命中 {} 条三元组", triples.size());
                return filterValidTriples(triples);
            }
        }

        return Collections.emptyList();
    }

    /**
     * 模糊查询三元组（处理别名、简称、错别字）
     */
    private List<Triple> queryFuzzyTriples(QuestionInfo questionInfo) {
        Set<Triple> fuzzyResults = new HashSet<>();

        // 收集所有可能的实体候选
        List<String> candidateEntities = new ArrayList<>();
        if (questionInfo.getKnownHeadEntity() != null) {
            candidateEntities.add(questionInfo.getKnownHeadEntity());
        }
        if (questionInfo.getKnownTailEntity() != null) {
            candidateEntities.add(questionInfo.getKnownTailEntity());
        }
        candidateEntities.addAll(questionInfo.getEntities());

        // 对每个候选实体进行模糊匹配
        for (String entityName : candidateEntities) {
            List<KgEntity> fuzzyEntities = kgEntityMapper.fuzzySelectByName(entityName);
            log.info("实体模糊匹配：{} → 找到 {} 个候选实体", entityName, fuzzyEntities.size());

            for (KgEntity entity : fuzzyEntities) {
                // 查询该实体作为头的三元组
                List<Triple> headTriples = questionInfo.getRelationType() != null
                        ? tripleMapper.selectTriplesByHeadEntityIdAndRelationType(entity.getId(), questionInfo.getRelationType())
                        : tripleMapper.selectTriplesByHeadEntityId(entity.getId());

                // 查询该实体作为尾的三元组
                List<Triple> tailTriples = questionInfo.getRelationType() != null
                        ? tripleMapper.selectTriplesByTailEntityIdAndRelationType(entity.getId(), questionInfo.getRelationType())
                        : tripleMapper.selectTriplesByTailEntityId(entity.getId());

                // 添加到结果集（自动去重）
                fuzzyResults.addAll(headTriples);
                fuzzyResults.addAll(tailTriples);
            }
        }

        log.info("模糊查询共命中 {} 条三元组", fuzzyResults.size());
        return new ArrayList<>(fuzzyResults);
    }

    /**
     * 过滤有效的三元组（根据业务规则）
     */
    private List<Triple> filterValidTriples(List<Triple> triples) {
        // 1. 过滤低置信度的关系（如果有置信度字段）
        // 2. 可以添加其他业务过滤规则
        return triples.stream()
                .filter(triple -> {
                    // 示例：过滤置信度低于0.5的关系
                    if (triple.getRelationConfidence() != null) {
                        return triple.getRelationConfidence() >= 0.5;
                    }
                    return true;
                })
                .sorted((t1, t2) -> {
                    // 按置信度降序排序（高置信度优先）
                    if (t1.getRelationConfidence() != null && t2.getRelationConfidence() != null) {
                        return Double.compare(t2.getRelationConfidence(), t1.getRelationConfidence());
                    }
                    return 0;
                })
                .collect(Collectors.toList());
    }

    /**
     * 生成无结果时的友好响应
     */
    private String generateNoResultResponse(QuestionInfo questionInfo) {
        if (!questionInfo.getEntities().isEmpty()) {
            String entitiesStr = String.join("、", questionInfo.getEntities());
            return String.format("抱歉，暂时没有找到关于“%s”的相关历史信息。\n" +
                            "您可以尝试：\n" +
                            "- 确认名称是否正确（例如“赢政”应为“嬴政”）\n" +
                            "- 询问更具体的问题（例如“%s的出生地在哪里？”）",
                    entitiesStr, entitiesStr.split("、")[0]);
        } else if (questionInfo.getRelationType() != null) {
            return String.format("抱歉，暂时没有找到关于“%s”的相关历史关系。\n" +
                            "您可以尝试补充具体实体，例如：\n" +
                            "- “%s和谁有关？”\n" +
                            "- “谁与谁存在%s关系？”",
                    questionInfo.getRelationType(),
                    questionInfo.getRelationType(),
                    questionInfo.getRelationType());
        } else {
            return "抱歉，没有找到相关历史信息。\n" +
                    "您可以尝试：\n" +
                    "- 询问更具体的历史人物或事件\n" +
                    "- 检查问题中是否有错别字\n" +
                    "- 例如：“汉武帝时期的改革有哪些？”";
        }
    }
}
